import { TMap } from '../map'
import { Point } from '../entity'
import { LngLat, LngLatBounds } from '../entity/lngLat'

import { Overlay } from './overlay'
import { LineStyle } from './style'
import { DefinedOverlayTypeEnum } from './enum'

/**
 * 矩形覆盖物的属性对象
 */
export interface RectangleOptions {
    /**
     * 矩形边线颜色
     *
     * 默认值为 `'#0000FF'`
     */
    color?: string;

    /**
     * 矩形边线的宽度，以像素为单位
     *
     * 默认值为 `3`
     */
    weight?: number;

    /**
     * 矩形边线的透明度（范围 `0-1` 之间）
     *
     * 默认值为 `0.5`
     */
    opacity?: number;

    /**
     * 矩形填充颜色。
     * 当参数为空时，矩形覆盖物将没有填充效果
     *
     * 默认值为 `'#0000FF'`
     */
    fillColor?: string;

    /**
     * 矩形填充的透明度（范围 `0-1` 之间）
     *
     * 默认值为 `0.2`
     */
    fillOpacity?: number;

    /**
     * 矩形边线的样式
     *
     * 默认值为 `'solid'`
     */
    lineStyle?: LineStyle
}

/**
 * 矩形覆盖物事件工厂对象
 */
type RectangleEventFactory = {
    /**
     * 点击矩形后会触发此事件
     */
    click: (event: { type: 'click', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 双击矩形后会触发此事件
     */
    dblclick: (event: { type: 'dblclick', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 鼠标在矩形上按下触发此事件
     */
    mousedown: (event: { type: 'mousedown', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 鼠标在矩形释放触发此事件
     */
    mouseup: (event: { type: 'mouseup', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 鼠标离开矩形时触发此事件
     */
    mouseout: (event: { type: 'mouseout', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 当鼠标进入矩形区域时会触发此事件
     */
    mouseover: (event: { type: 'mouseover', target: Rectangle, lnglat: LngLat, containerPoint: Point }) => void;

    /**
     * 移除矩形时触发
     */
    remove: (event: { type: 'remove', target: Rectangle }) => void;
}

/**
 * 此类表示一个矩形覆盖物
 */
export interface Rectangle extends Overlay {
    readonly bounds: LngLatBounds;
    readonly options: RectangleOptions;
    
    /**
     * 创建矩形覆盖物
     *
     * @param bounds 矩形范围
     *
     * @param options 矩形的属性对象
     */
    new (bounds: LngLatBounds, options?: RectangleOptions): Rectangle;

    /**
     * 叠加层类型
     */
    getType: () => DefinedOverlayTypeEnum.Rectangle;

    /**
     * 返回矩形的地理区域范围
     */
    getBounds: () => LngLatBounds;
    /**
     * 设置矩形的显示范围
     *
     * @param bounds 矩形的坐标范围
     */
    setBounds: (bounds: LngLatBounds) => void;

    /**
     * 返回矩形边线的颜色
     */
    getColor: () => string;
    /**
     * 设置矩形边线的颜色
     *
     * @param color 合法的 `CSS` 颜色值
     */
    setColor: (color: string) => void;

    /**
     * 返回矩形边线的透明度
     */
    getOpacity: () => number;
    /**
     * 设置矩形边线的透明度
     *
     * @param opacity 取值范围 `0-1` 之间
     */
    setOpacity: (opacity: number) => void;

    /**
     * 返回矩形边线的宽度
     */
    getWeight: () => number;
    /**
     * 设置矩形边线的宽度
     *
     * @param weight 范围为大于等于 `1` 的整数
     */
    setWeight: (weight: number) => void;

    /**
     * 返回当前矩形边线样式状态，实线或者虚线
     */
    getLineStyle: () => LineStyle;
    /**
     * 设置矩形边线样式状态，实线或者虚线
     *
     * @param weight 矩形边线样式状态
     */
    setLineStyle: (weight: LineStyle) => void;

    /**
     * 返回矩形的填充颜色
     */
    getFillColor: () => string;
    /**
     * 设置矩形的填充颜色，参数为合法的CSS颜色值。
     * 当参数为空字符串时，矩形覆盖物填充颜色与边线颜色相同
     *
     * @param color 合法的 `CSS` 颜色值
     */
    setFillColor: (color: string) => void;

    /**
     * 返回矩形的填充透明度
     */
    getFillOpacity: () => number;
    /**
     * 设置矩形的填充透明度。
     * 当参数为 `0` 时，矩形覆盖物将没有填充效果
     *
     * @param opacity 取值范围 `0-1` 之间
     */
    setFillOpacity: (opacity: number) => void;

    /**
     * 返回矩形所在的 `map` 对象
     */
    getMap: () => TMap;

    /**
     * 是否启用线编辑功能，`true` 表示启用，`false` 表示禁止
     */
    isEditable: () => boolean;
    /**
     * 启用线编辑功能
     */
    enableEdit: () => void;
    /**
     * 禁用线编辑功能
     */
    disableEdit: () => void;

    /**
     * 添加事件监听函数
     */
    addEventListener: <Event extends keyof RectangleEventFactory>(event: Event, handler: RectangleEventFactory[Event]) => void;
    
    /**
     * 移除事件监听函数
     */
    removeEventListener: <Event extends keyof RectangleEventFactory>(event: Event, handler: RectangleEventFactory[Event]) => void
}
